﻿using FluentValidation;
using Mes.Domain.BoundedContext;
using Mes.Application.DTO.Inputs.Operations;
using Mes.Application.DTO.Results.Operations;
using Mes.Application.Services.Operations;
using Microsoft.AspNetCore.Mvc;
using Mes.Application.Common;

namespace Mes.Application.Web.Controllers.Operations
{
    /// <summary>
    /// 工艺控制器
    /// </summary>
    [ApiController]
    [Route("/api/v1")]
    public class ProcessController : ControllerBase
    {
        private readonly IProcessService _processService;
        private readonly IValidator<AddingProcessInput> _addProcessInputValidator;
        private readonly IValidator<QueryingProcessesInput> _getProcessesInputValidator;
        private readonly IValidator<UpdatingProcessInput> _updateProcessInputValidator;
        private readonly IOperService _operService;

        /// <summary>
        /// 工艺控制器
        /// </summary>
        /// <param name="processService"></param>
        /// <param name="addProcessInputValidator"></param>
        /// <param name="getProcessesInputValidator"></param>
        /// <param name="updateProcessInputValidator"></param>
        /// <param name="operService"></param>
        public ProcessController(IProcessService processService, IValidator<AddingProcessInput> addProcessInputValidator, IValidator<QueryingProcessesInput> getProcessesInputValidator, IValidator<UpdatingProcessInput> updateProcessInputValidator, IOperService operService)
        {
            _processService = processService;
            _addProcessInputValidator = addProcessInputValidator;
            _getProcessesInputValidator = getProcessesInputValidator;
            _updateProcessInputValidator = updateProcessInputValidator;
            _operService = operService;
        }

        /// <summary>
        /// 新增工艺
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("process")]
        public async Task<ActionResult> AddProcessAsync([FromBody] AddingProcessInput input)
        {
            try
            {
                var result = await _addProcessInputValidator.ValidateAsync(input);
                if (!result.IsValid)
                {
                    return BadRequest(result.Errors.First().ErrorMessage);
                }
                await _processService.AddProcessAsync(input);
                if (input.Process_Route_Id > 0)
                {
                    await _operService.AddOperationAsync(new OperInput { Process_Id = input.Process_Id, Process_Route_Id = input.Process_Route_Id });
                }  
                return Ok();
            }
            catch (CustomException ex)
            {
                return BadRequest(ex.Message);
            }
        }

        /// <summary>
        /// 编辑工艺
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPatch("process")]
        public async Task<ActionResult> UpdateProcessAsync([FromBody] UpdatingProcessInput input)
        {
            try
            {
                var result = await _updateProcessInputValidator.ValidateAsync(input);
                if (!result.IsValid)
                {
                    return BadRequest(result.Errors.First().ErrorMessage);
                }
                await _processService.UpdateProcessAsync(input);
                return Ok();
            }
            catch (CustomException ex)
            {
                return BadRequest(ex.Message);
            }
        }

        /// <summary>
        /// 删除工艺
        /// </summary>
        /// <param name="process_id"></param>
        /// <returns></returns>
        [HttpDelete("processes")]
        public async Task<ActionResult> DeleteProcessesAsync(string process_id)
        {
            try
            {
                var opres = await _processService.GetProcessOpersAsync(process_id);
                if (opres.Count > 0)
                {
                    await _operService.DeleteOperationAsync(process_id, opres.ToArray());
                }
                await _processService.DeleteProcessAsync(process_id);
                return Ok();
            }
            catch (CustomException ex)
            {
                return BadRequest(ex.Message);
            }
        }

        /// <summary>
        /// 查询工艺分页列表
        /// </summary>
        /// <param name="input"></param>
        /// <returns>PagedItemsData<ProcessesResult></returns>
        [HttpGet("processes")]
        public async Task<ActionResult<PagedItemsData<ProcessesResult>>> GetProcessesAsync([FromQuery] QueryingProcessesInput input)
        {
            try
            {
                var result = await _getProcessesInputValidator.ValidateAsync(input);
                if (!result.IsValid)
                {
                    return BadRequest(result.Errors.First().ErrorMessage);
                }
                var processes = await _processService.GetProcessesAsync(input);
                return Ok(processes);
            }
            catch (CustomException ex)
            {
                return BadRequest(ex.Message);
            }
        }

        /// <summary>
        /// 查询工艺实体
        /// </summary>
        /// <param name="process_id"></param>
        /// <returns>CurrentProcessResult</returns>
        [HttpGet("process")]
        public async Task<ActionResult<CurrentProcessResult>> GetProcessAsync(string process_id)
        {
            try
            {
                var response = await _processService.GetProcessAsync(process_id);
                return Ok(response);
            }
            catch (CustomException ex)
            {
                return BadRequest(ex.Message);
            }
        }


        /// <summary>
        /// 移动工序顺序
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPatch("process/oper/route")]
        public async Task<ActionResult> MovingOperSequenceAsync(MovingOperSequenceInput input)
        {
            try
            {
                await _processService.MovingOperSequenceAsync(input);
                return Ok();
            }
            catch (CustomException ex)
            {
                return BadRequest(ex.Message);
            }
        }

        /// <summary>
        /// 通过工艺路线添加工序
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("process/opers")]
        public async Task<ActionResult> AddProcessOpersAsync([FromBody] AddProcessOpersInput input)
        {
            try
            {
                await _processService.AddProcessOpersAsync(input);
                return Ok();
            }
            catch (CustomException ex)
            {
                return BadRequest(ex.Message);
            }
        }
    }
}
